package de.jmda.core.util.ramcomp;

import static java.lang.System.lineSeparator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import de.jmda.core.util.ramcomp.RAMCompiler.RAMCompilerData;

public class JUTRAMCompiler
{
	@Test
	public void compileRunSingle()
			throws
					InstantiationException,
					IllegalAccessException,
					ClassNotFoundException,
					IOException
	{
		List<RAMCompilerData> items = createRAMCompilerDataItems(1);

		RAMCompiler.compile(items);
		
		for (RAMCompilerData item : items)
		{
			Object object =
					item.getClassLoader()
					    .loadClass(item.getQualifiedTypeName()).newInstance();

			((Runnable) object).run();
		}
	}

	@Test
	public void compileRunMany()
			throws
					InstantiationException,
					IllegalAccessException,
					ClassNotFoundException,
					IOException
	{
		List<RAMCompilerData> items = createRAMCompilerDataItems(10);

		RAMCompiler.compile(items);
		
		for (RAMCompilerData item : items)
		{
			Object object =
					item.getClassLoader()
					    .loadClass(item.getQualifiedTypeName()).newInstance();

			((Runnable) object).run();
		}
	}

	private List<RAMCompilerData> createRAMCompilerDataItems(int count)
	{
		List<RAMCompilerData> result = new ArrayList<>();

		for (int i = 0; i < count; i++)
		{
			result.add(createRAMCompilerDataItem(i));
		}
		
		return result;
	}

	private RAMCompilerData createRAMCompilerDataItem(int i)
	{
		String typename = "__DynaClass__" + i;
		
		String source =
				"public class " + typename + " " + "implements " + Runnable.class.getName() + lineSeparator() +
				"{"                                                                         + lineSeparator() +
				"	 @Override"                                                               + lineSeparator() +
				"	 public void run() { System.out.println(getClass().getName()); }"         + lineSeparator() +
				"}";

		return new RAMCompilerData(typename, source);
	}
}